Skip to content

[Add] AttributeValueXHTML.ExtractNormalizedTextFromValue for plain text with normalized whitespace; fixes #92 - #102

Merged
samatstariongroup merged 2 commits into
developmentfrom
GH92
Oct 19, 2026
Merged

samatstariongroup merged 2 commits into
developmentfrom
GH92

Conversation

@samatstariongroup

Copy link
Copy Markdown
Member

Prerequisites

  • I have written a descriptive pull-request title
  • I have verified that there are no overlapping pull-requests open
  • I have verified that I am following the ReqIFSharp code style guidelines
  • I have provided test coverage for my change (where applicable)

Description

Fixes #92.

AttributeValueXHTML.ExtractUnformattedTextFromValue() joins the text nodes with a space, so its result has extra spaces around inline elements and keeps the line breaks and indentation of the XHTML source (brew a cup in under 30 seconds .). This adds a second method and leaves the existing one unchanged.

New: ExtractNormalizedTextFromValue(bool keepLineBreaks = false)

  • Text is joined as it is written, so no space is added around inline elements: the example from the issue gives brew a cup in under 30 seconds.
  • Outside pre, runs of space, tab, carriage return and line feed are collapsed to one space, and each line is trimmed.
  • Block elements (p, div, li, headings, blockquote, dl/dt/dd, table, tr, ...) and br separate lines; table cells are separated by a space. Lines are joined with a space, or with \n when keepLineBreaks is true.
  • The text of pre is kept as written (spaces, tabs, indentation, one line per source line); blank lines at its start and end are left out, blank lines inside it are kept only with keepLineBreaks.
  • Non-breaking spaces (U+00A0) are kept: not collapsed, replaced or trimmed.
  • XML entities and character references are expanded; HTML named entities such as   and é (which no DTD declares in ReqIF) are decoded with WebUtility.HtmlDecode; an unknown entity throws an XmlException with its line and position.
  • The value is read as an XML fragment, so several top-level elements, plain text and undeclared prefixes work, and error positions are those in the value. DTD processing is prohibited and no resolver is used.

These rules for pre, non-breaking spaces and entities were decided during the review.

ExtractUnformattedTextFromValue is unchanged; a test pins its output for the example. Note that it still drops HTML named entities silently (café gives caf).

Tests (AttributeValueXHTMLTestFixture)

The issue example; empty values; source line breaks and indentation; every block and cell element with and without keepLineBreaks, including upper-case and unprefixed names; whitespace between inline elements and xml:space="preserve"; non-breaking spaces; pre (CRLF and lone CR, indentation, blank lines, br, inline elements, nested and adjacent blocks, empty pre); several top-level elements, plain text, CDATA, comments and processing instructions; attribute values (also with an entity) not in the text; references and HTML entities; unknown entities and malformed values with their exact line and column; DOCTYPE rejected; every XHTML value of reqifsharpgenerated.reqif.

dotnet build -c Release: 0 warnings; dotnet test: 620 passed. The README quick-start mentions the new method.

🤖 Generated with Claude Code

samatstarion and others added 2 commits October 19, 2026 16:46
…xt with normalized whitespace; fixes #92

ExtractUnformattedTextFromValue joins the text nodes with a space, so the
result has extra spaces around inline elements and keeps the line breaks
and indentation of the XHTML source.

- Add ExtractNormalizedTextFromValue(bool keepLineBreaks = false):
  - text is joined as written; outside pre, runs of space, tab, CR and LF
    are collapsed to one space and each line is trimmed;
  - block elements and br separate lines, table cells a space; lines are
    joined with a space or, with keepLineBreaks, a line feed;
  - pre text is kept as written, without blank lines at its start and end;
  - non-breaking spaces are kept; HTML named entities such as   are
    decoded, an unknown entity throws an XmlException;
  - the value is read as an XML fragment (several top-level elements,
    plain text, undeclared prefixes), with DTD processing prohibited;
    error positions are those in the value.
- ExtractUnformattedTextFromValue is unchanged.
- Mention the new method in the README quick-start.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The comments in the test fixtures referred to GH-87, GH-92, GH-94, GH-95,
GH-97, GH-98 and issue #44. They now describe the behaviour instead; the
issues are linked from the CHANGELOG and the pull requests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@samatstariongroup
samatstariongroup merged commit 0b78164 into development Oct 19, 2026
8 checks passed
@samatstariongroup
samatstariongroup deleted the GH92 branch October 19, 2026 15:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Plain text with normalized whitespace from AttributeValueXHTML

1 participant